/*
 * Copyright (c) 2008, Yifu Huang
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of SleekIce nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package com.sleekice.gui;

import com.sleekice.util.GL;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;

public class TextField extends Button implements Keyable {

    private String text;
    private String password;
    private static final Font DEF_FONT =
        new Font("Verdana", Font.PLAIN, 12);
    private Font font_;
    private static final int DEF_LEFT_SPC = 3;
    private static final int DEF_RIGHT_SPC = 3;
    private static final int DEF_TOP_SPC = 3;
    private static final int DEF_BOTTOM_SPC = 3;
    private int leftSpc = DEF_LEFT_SPC;
    private int rightSpc = DEF_RIGHT_SPC;
    private int topSpc = DEF_TOP_SPC;
    private int bottomSpc = DEF_BOTTOM_SPC;
    private int drawX; /* this is the x coordinate to draw the text */
    private int drawY; /* this is the y coordinate to draw the text */
    private boolean passworded_ = false;

    public TextField(int x, int y, int width, int height) {
        this(DEF_FONT, x, y, width, height);
    }

    public TextField(Font font, int x, int y, int width, int height) {
        super(x, y, width, height);
        font_ = font;

        /* resize and shrink the font if too large */
        resize(width, height);

        setButtonColor(Color.white);
        setButtonHoverColor(GL.blueRoyal);
        text = "";
        password = "";

        FontMetrics fontMetrics = GL.g.getFontMetrics(font_);
        drawX = x + leftSpc;
        drawY = fontMetrics.getAscent() + topSpc + y;
    }

    @Override
    public void resize(int width, int height) {
        FontMetrics fontMetrics = GL.g.getFontMetrics(font_);
        int changeHeight = height - bounds.height;

        /**
         * If the height is decreasing, make sure the text can fit.
         */
        if (changeHeight < 0) {
            fontMetrics = GL.g.getFontMetrics(font_);
            while (fontMetrics.getHeight() > height - topSpc - bottomSpc) {
                /**
                 * Decrease font size.
                 */
                font_ = font_.deriveFont(font_.getSize() - 1f);
                fontMetrics = GL.g.getFontMetrics(font_);
            }
        }
        drawY = fontMetrics.getAscent() + topSpc + bounds.y;

        super.resize(width, height);
    }

    @Override
    public void render(Graphics2D g) {
        super.render(g);
        g.setFont(font_);
        g.setColor(Color.black);
        String temp;
        if (passworded_) {
            temp = password;
        }
        else {
            temp = text;
        }

        if (focused_) {
            g.drawString(temp.substring(strIndex) + "|",
                drawX + (int) offsetPoint.getX(),
                drawY + (int) offsetPoint.getY());
        }
        else {
            g.drawString(temp.substring(strIndex),
                drawX + (int) offsetPoint.getX(),
                drawY + (int) offsetPoint.getY());
        }
    }

    public void setPassworded(boolean passworded) {
        passworded_ = passworded;
    }
    int strIndex = 0;

    public void addChar(char c) {
        text = text + String.valueOf(c);
        password += "*";

        String temp;
        if (passworded_) {
            temp = password;
        }
        else {
            temp = text;
        }
        FontMetrics fontMetrics = GL.g.getFontMetrics(font_);
        if (focused_) {
            while (fontMetrics.stringWidth((temp + "|").substring(strIndex)) >
                bounds.width - leftSpc - rightSpc) {
                strIndex++;
            }
        }
        else {
            while (fontMetrics.stringWidth(temp.substring(strIndex)) >
                bounds.width - leftSpc - rightSpc) {
                strIndex++;
            }
        }
    }

    public void removeChar() {
        if (text.length() > 0) {
            text = text.substring(0, text.length() - 1);
            password = password.substring(0, password.length() - 1);

            String temp;
            if (passworded_) {
                temp = password;
            }
            else {
                temp = text;
            }
            FontMetrics fontMetrics =
                GL.g.getFontMetrics(font_);
            while (true) {
                if (strIndex > 0) {
                    if (focused_) {
                        if (fontMetrics.stringWidth((temp + "|").substring(strIndex -
                            1)) > bounds.width - leftSpc - rightSpc) {
                            break;
                        }
                        else {
                            strIndex--;
                        }
                    }
                    else {
                        if (fontMetrics.stringWidth(temp.substring(strIndex - 1)) >
                            bounds.width - leftSpc - rightSpc) {
                            break;
                        }
                        else {
                            strIndex--;
                        }
                    }
                }
                else {
                    break;
                }
            }
        }
    }
    boolean focused_ = false;

    public void setFocused(boolean focused) {
        focused_ = focused;
    }
}